//
//  PMRotaryLimitJoint.m
//  PezMonkey
//
//  Created by Spence DiNicolantonio on 12/30/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

/**
 * A subclass of PMConstraint for representing rotary limit joints. PMRotaryLimitJoints
 * constrain the relative rotation angle of two rigid bodies. A PMRotaryLimitJoint
 * is defined with a minimum and maximum relative rotation angle that describe
 * range of relative rotation between the joint's bodies. PMRotaryLimitJoints do
 * allow minimum and maximum angle values greater than 2pi radians.
 */

#import "PMRotaryLimitJoint.h"
#import "PMBody.h"


@implementation PMRotaryLimitJoint


#pragma mark -
#pragma mark Init

/**
 * Returns a PMRotaryLimitJoint object initialized to constrain the relative 
 * rotation angle between two given rigid bodies to a given range.
 */
- (id)initWithBodyA:(PMBody *)aBody bodyB:(PMBody *)otherBody limit:(PMRange)limit {
	if (![super init])
		return nil;
	
	// allocate and initialize cpConstraint
	constraint = cpRotaryLimitJointNew(aBody.cpBody, otherBody.cpBody, limit.min, limit.max);
	
	// set body references
	self.bodyA = aBody;
	self.bodyB = otherBody;
	
	// reference this PMConstraint object with cpConstraint's data pointer
	// this is for internal use
	constraint->data = self;
	
	return self;
}

#pragma mark Convenience

/**
 * Creates and returns a PMRotaryLimitJoint object initialized to constrain the 
 * relative rotation angle between two given rigid bodies to a given range.
 */
+ (PMRotaryLimitJoint *)rotaryLimitJointWithBodyA:(PMBody *)aBody bodyB:(PMBody *)otherBody limit:(PMRange)limit {
	return [[[PMRotaryLimitJoint alloc] initWithBodyA:aBody 
												bodyB:otherBody 
												limit:limit] autorelease];
}


#pragma mark -
#pragma mark Getters

/**
 * Returns a PMRange defining the allowed relative rotation between the receiver's
 * rigid bodies.
 */
- (PMRange)limit {
	PMRange limit;
	limit.min = cpRotaryLimitJointGetMin(constraint);
	limit.max = cpRotaryLimitJointGetMax(constraint);
	return limit;
}


#pragma mark -
#pragma mark Setters

/**
 * Sets the relative rotation allowed between the receiver's rigid bodies to a 
 * given range of radian values.
 */
- (void)setLimit:(PMRange)limit {
	cpRotaryLimitJointSetMin(constraint, limit.min);
	cpRotaryLimitJointSetMax(constraint, limit.max);
}

@end
